/**
 * @author Kristian Mandrup
 * @date June 10, 2009
 * @version 0.1
 * 
 * m3gen :: Languages functions
 * 
 * Utility functions for parsing and operating on languages data
 * 
 * Status: DONE
 */ 


/* 
 * selectLanguages returns
 * 		var languages = {
			en: {},
			dk: {}
		};
 */

/**
 * Public
 * Resolve the Languages of a jsonObj using the title rule defined in the active ruleSet
 * @param {Object} ruleSet
 * @param {Object} jsonObj
 * 
 * Genrates a model in this format:
 * 
 * languages: {
 * 	'dk': {title: 'min titel', icon: 'danish/folder.png', attributes: {...}},
 *  'en': {title: 'my titel', icon: 'english/folder.png', attributes: {...}},  
 * }
 * 
 * TODO: Remove ruleSet from params
 */

m3gen.Base.prototype.resolveRuleSetLanguages = function (ruleSet, jsonObj) {
	var selectLanguages = this.getActiveFunctionsByRuleset(ruleSet).selectLanguages;		
	var title;
	var languages = {};						
	// is a selectLanguages function is defined, use this
	if (selectLanguages) {
		if (this.isFunction(selectLanguages)) {
			languages = selectLanguages(jsonObj, this.getContext(this));
		}
		else {
			languages = this.resolveLanguages(selectLanguages, jsonObj);
		}
		// iterate each key in languages and assign languageData
		for (var languageKey in languages) {
			languages[languageKey] = this.resolveLanguageData(languageKey, jsonObj);
		}
		
	} else {
		// otherwise use language keys as defined in container for language specific functions
		languagesFunctions = ruleSet.functions.languages;
		if (languagesFunctions) {
			for each(var languageKey in languagesFunctions) {
				languages[languageKey] = {};
			}
		} else {
			throw m3gen.exception.MissingLanguagesRule;		
		}
	}
	return languages;
}


/**
 * Public
 * Resolve the language data of a jsonObj using the language rule defined in the active ruleSet
 * Calls 
 * - resolveLanguageTitle
 * - resolveLanguageIcon
 * - resolveLanguageAttributes
 * 
 * @param {string} languageKey	-
 * @param {Object} jsonObj
 * 
 * @return {Object} - language data hashmap
 * 
 * TODO: Use options param
 */
m3gen.Base.prototype.resolveLanguageData = function (languageKey, jsonObj) {	
	var icon = this.resolveLanguageIcon(languageKey, jsonObj);
	var title = this.resolveLanguageTitle(languageKey,jsonObj);
	var attributes = this.resolveLanguageAttributes(languageKey, jsonObj);		

	var language = {
		title: title,
		icon: icon
	};
	if (!this.isEmptyObj(attributes)) {
		language.attributes = attributes;
	}
	return language;
}

/**
 * When languages is an object
 * 
 * @param {Object} languages
 * @param {Object} jsonObj
 * 
 *	languages = {
 *		en: {},
 *		dk: {}
 *	}
 * 
 * Return {Object} languages 
 * 
 * TODO: Use options param
 */
m3gen.Base.prototype.resolveLanguages = function (languages, jsonObj) {
	return languages;
}

/**
 * Public
 * Resolve the title of a jsonObj using the title rule defined in the active ruleSet
 * @param {string} languageKey
 * @param {Object} jsonObj
 * 
 * @return {string} - title or null
 * 
 * TODO: Use options param
 */
m3gen.Base.prototype.resolveLanguageTitle = function (languageKey, jsonObj) {	
	var selectTitle = this.getLanguageFunction(languageKey, 'selectTitle');		
	var title = null;	
	if (selectTitle) {
		if (this.isFunction(selectTitle)) {
			var options = this.getOptions('languages', 'title', languageKey);
			title = this.doSelect(selectTitle, 'Title', options);			
		}
		else 
			title = this.resolveTitle(selectTitle, jsonObj);
	} else {
		// throw m3gen.exception.MissingTitleRule;
	}
	return title;
}

/**
 * Public
 * Resolve the icon of a jsonObj using the icon rule defined in the active ruleSet
 * 
 * @param {string} languageKey
 * @param {Object} jsonObj
 * 
 * @return {string} - icon path or null
 * 
 * TODO: Use options param
 */
m3gen.Base.prototype.resolveLanguageIcon = function (languageKey, jsonObj) {			
	var languages = this.getActiveLanguages();
	var icon = null;
	if (languages) {
		var selectIcon = this.getLanguageFunction(languageKey, 'selectIcon');
		if (selectIcon) {
			if (this.isFunction(selectIcon)) {
				var options = this.getOptions('languages', 'icon', languageKey);
				icon = this.doSelect(selectIcon, 'Icon', options);
			}
			else 
				icon = this.resolveIcon(selectIcon, jsonObj);
		}
		else {			
			// throw m3gen.exception.MissingIconRule;
		}
	} 
	return icon;
}

/**
 * Public
 * Resolve the attributes of a jsonObj using the attributes rule defined in the active ruleSet
 * 
 * @param {string} languageKey
 * @param {Object} jsonObj
 * 
 * @return {Object} - attributes hash object or null
 * 
 * TODO: Use options param
 */
m3gen.Base.prototype.resolveLanguageAttributes = function (languageKey, jsonObj) {	
	var languages = this.getActiveLanguages();
	var attributes = null;
	if (languages) {
		var selectAttributes = this.getLanguageFunction(languageKey, 'selectAttributes');
		if (selectAttributes) {
			if (this.isFunction(selectAttributes)) {
				var options = this.getOptions('languages', 'attributes', languageKey);
				attributes = this.doSelect(selectAttributes, 'Attributes', options);
			}
			else {
				attributes = this.resolveAttributes(selectAttributes, jsonObj);
			}
		}
		else {
			// throw m3gen.exception.MissingLanguageAttributesRule;			
		}
	}
	return attributes;
}

/**
 * Get the active language
 * 
 * @param {Object} languageKey
 */
m3gen.Base.prototype.getActiveLanguage = function(languageKey) {
	var languages = this.getActiveLanguages();		
	return languages[languageKey] || this.getDefaultLanguage(languages);
}

/**
 * Set current active languageKey
 * @param {Object} languageKey
 */
m3gen.Base.prototype.setActiveLanguageKey = function(languageKey){
	this.languageKey = languageKey;
}

/**
 * Get current active languageKey
 */
m3gen.Base.prototype.getActiveLanguageKey = function(){
	return this.languageKey || '';
}

m3gen.Base.prototype.getLanguageFunction = function(languageKey, functionName) {
	var activeLang = this.getActiveLanguage(languageKey);
	if (activeLang) {
		var langFunc = activeLang[functionName];
		this.setActiveLanguageKey(languageKey);
		if (langFunc && this.isFunction(langFunc)) {
			
			return langFunc;
		}
		else {
			// this.setActiveLanguageKey('default');
			return this.getDefaultLanguage()[functionName];
		}
	} else console.log('getLanguageFunction: no lang');
}

/**
 * Get the languages of the active ruleSet
 */
m3gen.Base.prototype.getActiveLanguages = function() {
	var activeFunctions = this.getActiveFunctions();
	return activeFunctions.languages;
}

/**
 * Get default language using 'default' key
 * @param {Object} languages
 */
m3gen.Base.prototype.getDefaultLanguage = function(languages){
	if (languages)
		return languages['default'];
	else return this.getActiveLanguages()['default'];
}

// options

/**
 * Set currently active options obj
 * @param {Object} option
 */
m3gen.Base.prototype.setActiveOption = function(option) {
	this.activeOption = option;
}

/**
 * Get currently active options obj
 */
m3gen.Base.prototype.getActiveOption = function() {
	return this.activeOption;
}

/**
 * Get options by type, key and language
 * @param {Object} optionType
 * @param {Object} optionKey	- optional
 * @param {Object} languageKey 	- optional (find language specific options)
 */
m3gen.Base.prototype.getOptions = function(optionType, optionKey, languageKey) {
	var optionObj = this.getActiveOptionsByKey(optionType, languageKey);
	if (optionObj) {
		if (optionKey != undefined) {
			var option = optionObj[optionKey];
			this.setActiveOption(option);
			if (this.isValidObj(option)) {
				return option;
			}
			else {
				// this.setActiveLanguageKey('default');
				return this.getDefaultOption(optionType)[optionKey];
			}
		}
		this.setActiveOption(optionObj);
		return optionObj;
	} else console.log('No options found for keys:' + optionType + ', ' + optionKey);
}

/**
 * Get active options by a key, fx 'id' or 'title'
 * @param {Object} optionType
 * @param {Object} optionKey
 */
m3gen.Base.prototype.getActiveOptionsByKey = function(optionType, optionKey) {
	var activeOptions = this.getActiveOptions();
	if (activeOptions) {
		var options = activeOptions[optionType];
		if (optionKey) {
			return options[optionKey] || this.getDefaultOption(optionType, options);
		}
		else {
			return options;
		}
	} else {
		console.log('NO Active Options!! ' + optionType + ', ' + optionKey);
		return null;
	}
}

/**
 * Get the currently active set of options within the active funtions (in active ruleset)
 */
m3gen.Base.prototype.getActiveOptions = function() {
	var activeFunctions = this.getActiveFunctions();
	return activeFunctions.options;
}

/**
 * Get a specific language 'default' option
 */
m3gen.Base.prototype.getDefaultOption = function(optionType, options){
	if (options)
		return options['default'];
	else return this.getActiveOptions()[optionType]['default'];
}

